package com.chang.bootplus.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chang.bootplus.base.exception.BusException;
import com.chang.bootplus.base.utils.ApiResponse;
import com.chang.bootplus.base.utils.BeanUtil;
import com.chang.bootplus.base.utils.RedisUtil;
import com.chang.bootplus.entity.*;
import com.chang.bootplus.mapper.MenuMapper;
import com.chang.bootplus.mapper.SchoolMapper;
import com.chang.bootplus.mapper.StudentMapper;
import com.chang.bootplus.po.SchoolBackNamePO;
import com.chang.bootplus.po.SchoolNamePO;
import com.chang.bootplus.po.SchoolNeedPO;
import com.chang.bootplus.po.SchoolPO;
import com.chang.bootplus.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chang.bootplus.service.StuTestService;
import com.chang.bootplus.service.StudentService;
import com.chang.bootplus.vo.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author chang
 * @since 2022-01-23
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SchoolServiceImp extends ServiceImpl<SchoolMapper, School> implements SchoolService {


    final SchoolMapper schoolMapper;
    final MenuMapper menuMapper;
    final RoleService roleService;
    final StudentService studentService;
    final StuTestService stuTestService;
    final StudentMapper studentMapper;
    final RedisUtil redisUtil;
    final WxUserService wxUserService;
    final StuExeclService stuExeclService;

    @Autowired
    MenuService menuService;

    @Override
    public ApiResponse<Void> register(SchoolPO po) {
        School school = BeanUtil.beanA2beanB(po, School.class);
        if(getOne(new LambdaQueryWrapper<School>().eq(School::getSchoolName, po.getSchoolName())) == null){
            throw new BusException("该学校还未在后台进行添加！");
        }
        if(getOne(new LambdaQueryWrapper<School>().eq(School::getSchoolName, po.getSchoolName())).getPassword() != null){
            throw new BusException("该学校已经注册！");
        }
        String password = po.getPassword();
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        school.setPassword(encoder.encode(password));
        save(school);
        return new ApiResponse().setReMsg("注册成功");
    }

    @Override
    public ApiResponse<SchoolMessageVO> messageDisplay(SchoolNeedPO po) {
        String newTime = getNewTime(po.getSchoolName());
        int peopleCount1 = studentService.count(new LambdaQueryWrapper<Student>().eq(Student::getGmtCreate,newTime).eq(Student::getSchoolName,po.getSchoolName()));
        if(peopleCount1  == 0){
            throw new BusException("该学校没有一名学生信息被录入!");
        }
        SchoolMessageVO schoolMessageVO = new SchoolMessageVO();
        List<Student> list = studentService.list(new LambdaQueryWrapper<Student>().eq(Student::getGmtCreate,newTime).eq(Student::getSchoolName,po.getSchoolName()));

        List<StuTest> collect = new ArrayList<>();
        list.stream().forEach(student -> {
            StuTest one = stuTestService.getOne(new LambdaQueryWrapper<StuTest>().eq(StuTest::getStuId, student.getStuId())
                    .like(StuTest::getGmtCreate, po.getSelectTime()).isNotNull(StuTest::getScore));
            if(one != null){
                collect.add(one);
            }
        });

//        int peopleCount = studentService.count(new LambdaQueryWrapper<Student>().ne(Student::getScore,null).eq(Student::getSchoolName,po.getSchoolName()));
        int peopleCount = 0;
        int sum = 0;
        for(StuTest stuTest : collect){
            sum += stuTest.getScore();
            peopleCount++;
        }
        int average = sum /peopleCount;

        AtomicInteger good = new AtomicInteger();
        AtomicInteger excellent = new AtomicInteger();
        AtomicInteger failure = new AtomicInteger();
        AtomicInteger pass = new AtomicInteger();

        collect.stream().forEach(stuTest -> {
            double score = stuTest.getScore();
            if (score>=90&&score<=100){
                excellent.getAndIncrement();
                good.getAndIncrement();
                pass.getAndIncrement();
            }
            else if (score>=80&&score<=89){
                good.getAndIncrement();
                pass.getAndIncrement();
            }
            else if (score>=60&&score<=79){
                pass.getAndIncrement();
            }
            else{
                failure.getAndIncrement();
            }
        });


        String[] mapGrade = {"一年级","二年级","三年级","四年级","五年级","六年级","初一","初二","初三","高一","高二","高三","大一","大二","大三","大四"};
        Map<String,String> mapClass = new HashMap<>();
        int keyClassId = 100;
        for(int i=0;i<58;i++){
            keyClassId++;
            String tempId = "0"+keyClassId;
            String tempClassName = (i+1) + "班";
            mapClass.put(tempClassName,tempId);
        }



        schoolMessageVO.setAverage(average)
                .setExcellentRate((int)(excellent.get()*1.0/peopleCount * 100) + "%")
                .setFailureRate((int)(failure.get()*1.0/peopleCount * 100) + "%")
                .setGoodRate((int)(good.get()*1.0/peopleCount * 100) + "%")
                .setPassRate((int)(pass.get()*1.0/peopleCount * 100) + "%")
                .setPeopleCount(peopleCount1);

        int[] countOfProjectOfRank = new int[24];

        if(po.getGrade().equals("全部")){
            collect.stream().forEach(stuTest -> {
                int index = 0;
                countOfProjectOfRank[check(stuTest.getVital())+index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestFifty())+index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestSitRech())+index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestSkip())+index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestSitup())+index]++;
                // asdasd
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestRun())+index]++;
            });
        }else if(po.getStuClass().equals("全部")){
            String gradeId = "";
            for(int i=0;i<mapGrade.length;i++){
                if(mapGrade[i].equals(po.getGrade())){
                    gradeId = i+11+"";
                    break;
                }
            }

            String finalGradeId = gradeId;
            List<Student> studentsOfGrade = list.stream().filter(student -> student.getGradeId().equals(finalGradeId))
                    .collect(Collectors.toList());

            List<StuTest> stuTestsOfGrade = studentsOfGrade.stream().map(student -> stuTestService.getOne(new LambdaQueryWrapper<StuTest>()
                    .eq(StuTest::getStuId, student.getStuId()).like(StuTest::getGmtCreate,po.getSelectTime()))).collect(Collectors.toList());

            stuTestsOfGrade.stream().forEach(stuTest -> {
                int index = 0;
                countOfProjectOfRank[check(stuTest.getVital())+index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestFifty())+index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestSitRech())+index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestSkip())+index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestSitup())+index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestRun())+index]++;
            });
        }
        else{
            String gradeId = "";
            for(int i=0;i<mapGrade.length;i++){
                if(mapGrade[i].equals(po.getGrade())){
                    gradeId = i+11+"";
                    break;
                }
            }

            String classId = gradeId + mapClass.get(po.getStuClass());


            String finalGradeId = gradeId;
            List<Student> studentsOfGradeOfClass = list.stream().filter(student -> student.getGradeId().equals(finalGradeId))
                    .filter(student -> student.getClassId().equals(classId)).collect(Collectors.toList());

            List<StuTest> stuTestsOfGradeOfClass = studentsOfGradeOfClass.stream().map(student -> stuTestService.getOne(new LambdaQueryWrapper<StuTest>()
                    .eq(StuTest::getStuId, student.getStuId()).like(StuTest::getGmtCreate,po.getSelectTime()))).collect(Collectors.toList());

            stuTestsOfGradeOfClass.stream().forEach(stuTest -> {
                int index = 0;
                countOfProjectOfRank[check(stuTest.getVital())+index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestFifty())+index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestSitRech())+index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestSkip())+index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestSitup())+index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestRun())+index]++;
            });
        }


        int top = 0;
//        schoolMessageVO.setVitalExcellent(countOfProjectOfRank[top++])
//                .setVitalGood(countOfProjectOfRank[top++])
//                .setVitalPass(countOfProjectOfRank[top++])
//                .setVitalFailure(countOfProjectOfRank[top++])
//                .setTestFiftyExcellent(countOfProjectOfRank[top++])
//                .setTestFiftyGood(countOfProjectOfRank[top++])
//                .setTestFiftyPass(countOfProjectOfRank[top++])
//                .setTestFiftyFailure(countOfProjectOfRank[top++])
//                .setTestSitRechExcellent(countOfProjectOfRank[top++])
//                .setTestSitRechGood(countOfProjectOfRank[top++])
//                .setTestSitRechPass(countOfProjectOfRank[top++])
//                .setTestSitRechFailure(countOfProjectOfRank[top++])
//                .setTestSkipExcellent(countOfProjectOfRank[top++])
//                .setTestSkipGood(countOfProjectOfRank[top++])
//                .setTestSkipPass(countOfProjectOfRank[top++])
//                .setTestSkipFailure(countOfProjectOfRank[top++])
//                .setTestSitUpExcellent(countOfProjectOfRank[top++])
//                .setTestSitUpGood(countOfProjectOfRank[top++])
//                .setTestSitUpPass(countOfProjectOfRank[top++])
//                .setTestSitUpFailure(countOfProjectOfRank[top++])
//                .setTestRunExcellent(countOfProjectOfRank[top++])
//                .setTestRunGood(countOfProjectOfRank[top++])
//                .setTestRunPass(countOfProjectOfRank[top++])
//                .setTestRunFailure(countOfProjectOfRank[top++]);

//        List<SchoolOfProjectDetail> details = new ArrayList<>();
//        details.add(new SchoolOfProjectDetail().setName("肺活量优秀人数").setKey("vitalExcellent").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("肺活量良好人数").setKey("vitalGood").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("肺活量及格人数").setKey("vitalPass").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("肺活量不及格人数").setKey("vitalFailure").setCount(countOfProjectOfRank[top++]));
//
//        details.add(new SchoolOfProjectDetail().setName("50m跑优秀人数").setKey("testFiftyExcellent").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("50m跑良好人数").setKey("testFiftyGood").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("50m跑及格人数").setKey("testFiftyPass").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("50m跑不及格人数").setKey("testFiftyFailure").setCount(countOfProjectOfRank[top++]));
//
//        details.add(new SchoolOfProjectDetail().setName("坐位体前屈优秀人数").setKey("testSitRechExcellent").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("坐位体前屈良好人数").setKey("testSitRechGood").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("坐位体前屈及格人数").setKey("testSitRechPass").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("坐位体前屈不及格人数").setKey("testSitRechFailure").setCount(countOfProjectOfRank[top++]));
//
//        details.add(new SchoolOfProjectDetail().setName("1分钟跳绳优秀人数").setKey("testSkipExcellent").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("1分钟跳绳良好人数").setKey("testSkipGood").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("1分钟跳绳及格人数").setKey("testSkipPass").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("1分钟跳绳不及格人数").setKey("testSkipFailure").setCount(countOfProjectOfRank[top++]));
//
//        details.add(new SchoolOfProjectDetail().setName("仰卧起坐优秀人数").setKey("testSitUpExcellent").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("仰卧起坐良好人数").setKey("testSitUpGood").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("仰卧起坐及格人数").setKey("testSitUpPass").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("仰卧起坐不及格人数").setKey("testSitUpFailure").setCount(countOfProjectOfRank[top++]));
//
//        details.add(new SchoolOfProjectDetail().setName("50m*8折返跑优秀人数").setKey("testRunExcellent").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("50m*8折返跑良好人数").setKey("testRunGood").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("50m*8折返跑及格人数").setKey("testRunPass").setCount(countOfProjectOfRank[top++]));
//        details.add(new SchoolOfProjectDetail().setName("50m*8折返跑不及格人数").setKey("testRunFailure").setCount(countOfProjectOfRank[top++]));

        List<SchoolOfProjectDetail> details = new ArrayList<>();
        int[] count1 = new int[4];
        for(int i=0;i<4;i++){
            count1[i] = countOfProjectOfRank[top++];
        }
        details.add(new SchoolOfProjectDetail().setName("肺活量").setCount(count1));

        int[] count2 = new int[4];
        for(int i=0;i<4;i++){
            count2[i] = countOfProjectOfRank[top++];
        }
        details.add(new SchoolOfProjectDetail().setName("50m跑").setCount(count2));

        int[] count3 = new int[4];
        for(int i=0;i<4;i++){
            count3[i] = countOfProjectOfRank[top++];
        }
        details.add(new SchoolOfProjectDetail().setName("坐位体前屈").setCount(count3));

        int[] count4 = new int[4];
        for(int i=0;i<4;i++){
            count4[i] = countOfProjectOfRank[top++];
        }
        details.add(new SchoolOfProjectDetail().setName("1分钟跳绳").setCount(count4));

        int[] count5 = new int[4];
        for(int i=0;i<4;i++){
            count5[i] = countOfProjectOfRank[top++];
        }
        details.add(new SchoolOfProjectDetail().setName("仰卧起坐").setCount(count5));

        int[] count6 = new int[4];
        for(int i=0;i<4;i++){
            count6[i] = countOfProjectOfRank[top++];
        }
        details.add(new SchoolOfProjectDetail().setName("50m*8折返跑").setCount(count6));

        schoolMessageVO.setList(details);
        return new ApiResponse<>(schoolMessageVO);

    }

    @Override
    public ApiResponse<SchoolTestTimeVO> testTimeDisplay(SchoolNamePO po) {
        List<Student> list = studentService.list(new LambdaQueryWrapper<Student>().eq(Student::getSchoolName, po.getSchoolName()));
        if(list == null || list.size() == 0){
            throw new BusException("没有找到该学校名称");
        }
        List<List<StuTest>> collect = list.stream().map(student -> stuTestService.list(
                new LambdaQueryWrapper<StuTest>().eq(StuTest::getStuId, student.getStuId()))).collect(Collectors.toList());

        Map<String,Integer> map = new HashMap<>();  // 直接用Set就行

        collect.stream().forEach(stuTests -> {
            stuTests.stream().forEach(stuTest -> {
                LocalDateTime gmtCreate = stuTest.getGmtCreate();
                String datetime = gmtCreate.toString().substring(0, 10);
                map.put(datetime,1);
            });
        });

        Set<String> strings = map.keySet();
        List<String> listRes = new ArrayList<>();
        for(String ss: strings){
            listRes.add(ss);
        }
        listRes.sort((o1, o2) -> {
            String[] split1 = o1.split("-");
            String[] split2 = o2.split("-");

            Integer y1 = Integer.parseInt(split1[0].replaceAll("^(0+)", ""));
            Integer y2 = Integer.parseInt(split2[0].replaceAll("^(0+)", ""));
            Integer m1 = Integer.parseInt(split1[1].replaceAll("^(0+)", ""));
            Integer m2 = Integer.parseInt(split2[1].replaceAll("^(0+)", ""));
            Integer d1 = Integer.parseInt(split1[2].replaceAll("^(0+)", ""));
            Integer d2 = Integer.parseInt(split2[2].replaceAll("^(0+)", ""));

            if(y1.equals(y2)){
                if(m1.equals(m2)){
                    return d2-d1;
                }
                return m2 - m1;
            }

            return y2 - y1;
        });
        SchoolTestTimeVO schoolTestTimeVO = new SchoolTestTimeVO();
        schoolTestTimeVO.setTestTimes(listRes);
        return new ApiResponse<>(schoolTestTimeVO);
    }

    @Override
    public ApiResponse<SchoolGradeVO> testGradeDisPlay(SchoolNamePO po) {
        List<String> gradeIds = studentMapper.listGrades(po);
        if(gradeIds == null || gradeIds.size() == 0){
            throw new BusException("没有找到该学校名称");
        }
        String[] mapGrade = {"一年级","二年级","三年级","四年级","五年级","六年级","初一","初二","初三","高一","高二","高三","大一","大二","大三","大四"};
        List<String> collect = gradeIds.stream().map(gradeId -> mapGrade[Integer.parseInt(gradeId) - 11]).collect(Collectors.toList());
        SchoolGradeVO schoolGradeVO = new SchoolGradeVO();
        schoolGradeVO.setGrades(collect);
        return new ApiResponse<>(schoolGradeVO);
    }

    @Override
    public ApiResponse<SchoolClassVO> testClassDisplay(SchoolNamePO po) {
        List<String> gradeIds = studentMapper.listGrades(po);
        if(gradeIds == null || gradeIds.size() == 0){
            throw new BusException("没有找到该学校名称");
        }
        String[] mapGrade = {"一年级","二年级","三年级","四年级","五年级","六年级","初一","初二","初三","高一","高二","高三","大一","大二","大三","大四"};
        List<String> collect = gradeIds.stream().map(gradeId -> mapGrade[Integer.parseInt(gradeId) - 11]).collect(Collectors.toList());
        Map<String,Set<String>> resMap = new HashMap<>();

        Map<String,String> mapClass = new HashMap<>();
        int keyClassId = 100;
        for(int i=0;i<58;i++){
            keyClassId++;
            String tempId = "0"+keyClassId;
            String tempClassName = (i+1) + "班";
            mapClass.put(tempId,tempClassName);
        }

        int index = 0;
        for(String gradeId : gradeIds){
            List<Student> list = studentService.list(new LambdaQueryWrapper<Student>()
                    .eq(Student::getGradeId, gradeId).eq(Student::getSchoolName, po.getSchoolName()));

            Set<String> classStudent = list.stream().filter(student -> student.getClassId()!=null).filter(student -> student.getClassId().length()==6)
                    .map(student -> mapClass.get(student.getClassId().substring(2,6))).filter(s -> s!=null).collect(Collectors.toSet());
            resMap.put(collect.get((int)index++),classStudent);
        }

        SchoolClassVO schoolClassVO = new SchoolClassVO();
        schoolClassVO.setClassOfGrade(resMap);
        return new ApiResponse<>(schoolClassVO);
    }



    @Override
    public ApiResponse<SchoolBackMessageVO> schoolManage(SchoolBackNamePO po) {

        if(po.getSchoolName() != null && po.getSchoolName() != "" ){
            int count0 = count(new LambdaQueryWrapper<School>().like(School::getSchoolName, po.getSchoolName()));
            Long count = (long)count0;
            Page<School> page = new Page<>(po.getPageNumber(), po.getPageSize());
            List<School> list1 = page(page, new LambdaQueryWrapper<School>().like(School::getSchoolName,po.getSchoolName())).getRecords();
            List<SchoolBackMessageVO> schoolDetailPercentVOS1 = list1.stream().map(school -> getSchoolDetailPercent(school.getSchoolName()))
                    .filter(schoolBackMessageVO -> schoolBackMessageVO!=null).collect(Collectors.toList());

            return new ApiResponse<>(schoolDetailPercentVOS1,new Long(schoolDetailPercentVOS1.size()),count);
        }

        int count0 = count(new LambdaQueryWrapper<School>());
        Long count = (long)count0;
        Page<School> page = new Page<>(po.getPageNumber(), po.getPageSize());
        List<School> list2 = page(page, new LambdaQueryWrapper<>()).getRecords();

        List<SchoolBackMessageVO> schoolDetailPercentVOS2 = list2.stream().filter(school -> !school.getSchoolName().equals("admin"))
                .map(school -> getSchoolDetailPercent(school.getSchoolName()))
                .filter(schoolBackMessageVO -> schoolBackMessageVO!=null).collect(Collectors.toList());

        return new ApiResponse<>(schoolDetailPercentVOS2,new Long(schoolDetailPercentVOS2.size()),new Long(count));
    }

    @Override
    public ApiResponse<CountCalVO> countCal() {
        int schoolCount = count(new LambdaQueryWrapper<School>().ne(School::getSchoolName,"admin"));
        int userCount = wxUserService.count(new LambdaQueryWrapper<>());
        CountCalVO countCalVO = new CountCalVO();
        countCalVO.setUserCount(userCount).setSchoolCount(schoolCount);
        return new ApiResponse<>(countCalVO);
    }

    @Override
    public ApiResponse<WorkbenchDetailsVO> workbenchDetail(SchoolNamePO po) {
        if (!po.getSchoolName().equals("admin")) {
            SchoolBackMessageVO schoolDetailPercent = getSchoolDetailPercent(po.getSchoolName());
            WorkbenchDetailsVO workbenchDetailsVO = BeanUtil.beanA2beanB(schoolDetailPercent, WorkbenchDetailsVO.class);
            String newTime = getNewTime(po.getSchoolName());
            List<Student> list = studentService.list(new LambdaQueryWrapper<Student>().eq(Student::getSchoolName,
                    po.getSchoolName()).eq(Student::getGmtCreate,newTime)).stream().filter(student -> student.getScore() != null).collect(Collectors.toList());

            //  一个学校的测试时间应该都一样，也只能一样，因为后台ui限制了可以看到一个学校最新的测试时间的优秀率啥的
            //  下面的我这种查询方法，是通过先去student ， 再去stu_test ， 所以他这里是拿到每一个学生的最新时间 作为时间标准去查的，
            //  这样的话假如出现一种情况 --->  即一个学校的测试时间不是相同的，也可以正常运行，因为他是按照一个一个学生的方式去取的最新时间，所以拿到的是每一个学生的测试时间
            //  如果一个学校的测试时间一定相同的话，那其实可以直接去student表里拿一个时间，然后直接去test表里查就行
            //  下面的这个查找就是拿到这个学校的每一个学生的时间是最新的 stu_test 对象
            List<StuTest> stuTests = list.stream().map(student -> stuTestService.getOne(new LambdaQueryWrapper<StuTest>()
                    .eq(StuTest::getStuId, student.getStuId()).like(StuTest::getGmtCreate,
                            getRightTime(student.getGmtCreate().toString())))).filter(stuTest -> stuTest != null).collect(Collectors.toList());

            int[] countOfProjectOfRank = new int[24];


            stuTests.stream().forEach(stuTest -> {
                int index = 0;
                countOfProjectOfRank[check(stuTest.getVital()) + index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestFifty()) + index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestSitRech()) + index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestSkip()) + index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestSitup()) + index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestRun()) + index]++;
            });

            int top = 0;

            List<SchoolOfProjectDetail> details = new ArrayList<>();
            int[] count1 = new int[4];
            for (int i = 0; i < 4; i++) {
                count1[i] = countOfProjectOfRank[top++];
            }
            details.add(new SchoolOfProjectDetail().setName("肺活量").setCount(count1));

            int[] count2 = new int[4];
            for (int i = 0; i < 4; i++) {
                count2[i] = countOfProjectOfRank[top++];
            }
            details.add(new SchoolOfProjectDetail().setName("50m跑").setCount(count2));

            int[] count3 = new int[4];
            for (int i = 0; i < 4; i++) {
                count3[i] = countOfProjectOfRank[top++];
            }
            details.add(new SchoolOfProjectDetail().setName("坐位体前屈").setCount(count3));

            int[] count4 = new int[4];
            for (int i = 0; i < 4; i++) {
                count4[i] = countOfProjectOfRank[top++];
            }
            details.add(new SchoolOfProjectDetail().setName("1分钟跳绳").setCount(count4));

            int[] count5 = new int[4];
            for (int i = 0; i < 4; i++) {
                count5[i] = countOfProjectOfRank[top++];
            }
            details.add(new SchoolOfProjectDetail().setName("仰卧起坐").setCount(count5));

            int[] count6 = new int[4];
            for (int i = 0; i < 4; i++) {
                count6[i] = countOfProjectOfRank[top++];
            }
            details.add(new SchoolOfProjectDetail().setName("50x8折返跑").setCount(count6));

            workbenchDetailsVO.setList(details);
            return new ApiResponse<>(workbenchDetailsVO);
        } else {

            Set<String> collect1 = studentService.list(new LambdaQueryWrapper<>()).stream().map(student -> student.getSchoolName()).collect(Collectors.toSet());// 学校名集合
            List<String> schoolNewTimes = collect1.stream().map(s -> getNewTime(s)).collect(Collectors.toList());// 获取所有学校的最新测试时间


            SchoolBackMessageVO schoolDetailPercent = getSchoolDetailPercent(po.getSchoolName()); // 获取当前学校或所有学校的四个率
            WorkbenchDetailsVO workbenchDetailsVO = BeanUtil.beanA2beanB(schoolDetailPercent, WorkbenchDetailsVO.class);

            List<Student> list = new ArrayList<>();
            schoolNewTimes.stream().forEach(time -> list.addAll(studentService.list(new LambdaQueryWrapper<Student>().eq(Student::getGmtCreate,time)).stream()
                    .filter(student -> student.getScore() != null).collect(Collectors.toList())));//添加当前学校或所有学校学生

            List<StuTest> stuTests = list.stream().map(student -> stuTestService.list(new LambdaQueryWrapper<StuTest>()
                    .eq(StuTest::getStuId, student.getStuId()).like(StuTest::getGmtCreate,
                            getRightTime(student.getGmtCreate().toString()))).get(0))//

                    .filter(stuTest -> stuTest != null).collect(Collectors.toList());

            int[] countOfProjectOfRank = new int[24];

            stuTests.stream().forEach(stuTest -> {
                int index = 0;
                countOfProjectOfRank[check(stuTest.getVital()) + index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestFifty()) + index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestSitRech()) + index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestSkip()) + index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestSitup()) + index]++;
                index += 4;
                countOfProjectOfRank[check(stuTest.getTestRun()) + index]++;
            });

            int top = 0;

            List<SchoolOfProjectDetail> details = new ArrayList<>();
            int[] count1 = new int[4];
            for (int i = 0; i < 4; i++) {
                count1[i] = countOfProjectOfRank[top++];
            }
            details.add(new SchoolOfProjectDetail().setName("肺活量").setCount(count1));

            int[] count2 = new int[4];
            for (int i = 0; i < 4; i++) {
                count2[i] = countOfProjectOfRank[top++];
            }
            details.add(new SchoolOfProjectDetail().setName("50m跑").setCount(count2));

            int[] count3 = new int[4];
            for (int i = 0; i < 4; i++) {
                count3[i] = countOfProjectOfRank[top++];
            }
            details.add(new SchoolOfProjectDetail().setName("坐位体前屈").setCount(count3));

            int[] count4 = new int[4];
            for (int i = 0; i < 4; i++) {
                count4[i] = countOfProjectOfRank[top++];
            }
            details.add(new SchoolOfProjectDetail().setName("1分钟跳绳").setCount(count4));

            int[] count5 = new int[4];
            for (int i = 0; i < 4; i++) {
                count5[i] = countOfProjectOfRank[top++];
            }
            details.add(new SchoolOfProjectDetail().setName("仰卧起坐").setCount(count5));

            int[] count6 = new int[4];
            for (int i = 0; i < 4; i++) {
                count6[i] = countOfProjectOfRank[top++];
            }
            details.add(new SchoolOfProjectDetail().setName("50x8折返跑").setCount(count6));

            workbenchDetailsVO.setList(details);
            return new ApiResponse<>(workbenchDetailsVO);
        }

    }

    // 求一个学校的最新时间的优秀率等等信息
    public SchoolBackMessageVO getSchoolDetailPercent(String schoolName){
        if(schoolName.equals("admin")){
            Set<String> collect1 = studentService.list(new LambdaQueryWrapper<>()).stream().map(student -> student.getSchoolName()).collect(Collectors.toSet());
            List<String> schoolNewTimes = collect1.stream().map(s -> getNewTime(s)).collect(Collectors.toList());
//
//            List<Student> temp = schoolNewTimes.stream().map(time -> studentService.list(
//                    new LambdaQueryWrapper<Student>().like(Student::getGmtCreate, time)).stream()
//                    .sorted(Comparator.comparing(Student::getGmtCreate).reversed()).collect(Collectors.toList()).get(0)).collect(Collectors.toList());

            int peopleCount = schoolNewTimes.stream().mapToInt(time -> studentService
                    .count(new LambdaQueryWrapper<Student>().eq(Student::getGmtCreate, time).isNotNull(Student::getScore))).sum();

            int resCount = schoolNewTimes.stream().mapToInt(time -> studentService
                    .count(new LambdaQueryWrapper<Student>().eq(Student::getGmtCreate, time))).sum();

            if(peopleCount == 0){
                SchoolBackMessageVO vo = new SchoolBackMessageVO();
                Long schoolId = getOne(new LambdaQueryWrapper<School>().eq(School::getSchoolName, schoolName)).getId();
                vo.setId(schoolId);
                return vo.setSchoolName(schoolName).setPeopleCount(resCount).setExcellentRate("0%")
                        .setGoodRate("0%").setPassRate("0%").setFailureRate("0%");
            }
            SchoolBackMessageVO schoolBackMessageVO = new SchoolBackMessageVO();

            List<Student> list = new ArrayList<>();
            schoolNewTimes.stream().forEach(time -> list.addAll(studentService.list(new LambdaQueryWrapper<Student>()
                    .eq(Student::getGmtCreate,time).isNotNull(Student::getScore))));


            //  一个学校的测试时间应该都一样，也只能一样，因为后台ui限制了可以看到一个学校最新的测试时间的优秀率啥的
            List<StuTest> collect = list.stream().map(student -> stuTestService.list(new LambdaQueryWrapper<StuTest>()
                    .eq(StuTest::getStuId, student.getStuId()).like(StuTest::getGmtCreate,
                            getRightTime(student.getGmtCreate().toString()))).stream()
                            .sorted(Comparator.comparing(StuTest::getGmtCreate).reversed()).collect(Collectors.toList()).get(0))
                    .filter(stuTest -> stuTest!=null).filter(stuTest -> stuTest.getScore()!=null).collect(Collectors.toList());

            int sum = 0;
            for(StuTest stuTest : collect){
                sum += stuTest.getScore();
            }

            //  这里求优秀率啥的其实不用去stu_test表中查，为啥呢？   因为这里是直接拿最新的时间，不是指定的时间，
            //  然后最新的时间的分数的话其实在student表中查就行，因为student 里面有最新分数和最新时间了

            AtomicInteger good = new AtomicInteger();
            AtomicInteger excellent = new AtomicInteger();
            AtomicInteger failure = new AtomicInteger();
            AtomicInteger pass = new AtomicInteger();

            collect.stream().forEach(stuTest -> {
                double score = stuTest.getScore();
                if (score>=90&&score<=100){
                    excellent.getAndIncrement();
                    good.getAndIncrement();
                    pass.getAndIncrement();
                }
                else if (score>=80&&score<=89){
                    good.getAndIncrement();
                    pass.getAndIncrement();
                }
                else if (score>=60&&score<=79){
                    pass.getAndIncrement();
                }
                else{
                    failure.getAndIncrement();
                }
            });

            Long schoolId = getOne(new LambdaQueryWrapper<School>().eq(School::getSchoolName, schoolName)).getId();

            schoolBackMessageVO.setSchoolName(schoolName)
                    .setExcellentRate((int)(excellent.get()*1.0/peopleCount * 100) + "%")
                    .setFailureRate((int)(failure.get()*1.0/peopleCount * 100) + "%")
                    .setGoodRate((int)(good.get()*1.0/peopleCount * 100) + "%")
                    .setPassRate((int)(pass.get()*1.0/peopleCount * 100) + "%")
                    .setPeopleCount(resCount)
                    .setId(schoolId);

            return schoolBackMessageVO;
        }

        else{
            String newTime = getNewTime(schoolName);

            int resCount = studentService.count(new LambdaQueryWrapper<Student>()
                    .eq(Student::getSchoolName,schoolName).eq(Student::getGmtCreate,newTime));
            if(newTime == null){
                SchoolBackMessageVO vo = new SchoolBackMessageVO();
                Long schoolId = getOne(new LambdaQueryWrapper<School>().eq(School::getSchoolName, schoolName)).getId();
                vo.setId(schoolId);
                return vo.setSchoolName(schoolName).setPeopleCount(resCount).setExcellentRate("0%")
                        .setGoodRate("0%").setPassRate("0%").setFailureRate("0%");
            }
//            int peopleCount = studentService.count(new LambdaQueryWrapper<Student>()
//                    .eq(Student::getSchoolName,schoolName).eq(Student::getGmtCreate,newTime).isNotNull(Student::getScore));

            int peopleCount = studentService.count(new LambdaQueryWrapper<Student>()
                    .eq(Student::getSchoolName,schoolName).eq(Student::getGmtCreate,newTime).isNotNull(Student::getScore));


            if(peopleCount == 0){
                SchoolBackMessageVO vo = new SchoolBackMessageVO();
                Long schoolId = getOne(new LambdaQueryWrapper<School>().eq(School::getSchoolName, schoolName)).getId();
                vo.setId(schoolId);
                return vo.setSchoolName(schoolName).setPeopleCount(resCount).setExcellentRate("0%")
                        .setGoodRate("0%").setPassRate("0%").setFailureRate("0%");
            }
            SchoolBackMessageVO schoolBackMessageVO = new SchoolBackMessageVO();
            List<Student> list = studentService.list(new LambdaQueryWrapper<Student>().eq(Student::getSchoolName,schoolName)
                    .eq(Student::getGmtCreate,newTime).isNotNull(Student::getScore));


            //  一个学校的测试时间应该都一样，也只能一样，因为后台ui限制了可以看到一个学校最新的测试时间的优秀率啥的
            List<StuTest> collect = list.stream().map(student -> stuTestService.list(new LambdaQueryWrapper<StuTest>()
                    .eq(StuTest::getStuId, student.getStuId()).like(StuTest::getGmtCreate,
                                    getRightTime(student.getGmtCreate().toString()))).get(0))
                    .filter(stuTest -> stuTest!=null).filter(stuTest -> stuTest.getScore()!=null).collect(Collectors.toList());

            int sum = 0;
            for(StuTest stuTest : collect){
                sum += stuTest.getScore();
            }


            //  这里求优秀率啥的其实不用去stu_test表中查，为啥呢？   因为这里是直接拿最新的时间，不是指定的时间，
            //  然后最新的时间的分数的话其实在student表中查就行，因为student 里面有最新分数和最新时间了

            AtomicInteger good = new AtomicInteger();
            AtomicInteger excellent = new AtomicInteger();
            AtomicInteger failure = new AtomicInteger();
            AtomicInteger pass = new AtomicInteger();

            collect.stream().forEach(stuTest -> {
                double score = stuTest.getScore();
                if (score>=90&&score<=100){
                    excellent.getAndIncrement();
                    good.getAndIncrement();
                    pass.getAndIncrement();
                }
                else if (score>=80&&score<=89){
                    good.getAndIncrement();
                    pass.getAndIncrement();
                }
                else if (score>=60&&score<=79){
                    pass.getAndIncrement();
                }
                else{
                    failure.getAndIncrement();
                }
            });

            Long schoolId = getOne(new LambdaQueryWrapper<School>().eq(School::getSchoolName, schoolName)).getId();

            schoolBackMessageVO.setSchoolName(schoolName)
                    .setExcellentRate((int)(excellent.get()*1.0/peopleCount * 100) + "%")
                    .setFailureRate((int)(failure.get()*1.0/peopleCount * 100) + "%")
                    .setGoodRate((int)(good.get()*1.0/peopleCount * 100) + "%")
                    .setPassRate((int)(pass.get()*1.0/peopleCount * 100) + "%")
                    .setPeopleCount(resCount)
                    .setId(schoolId);

            return schoolBackMessageVO;
        }
    }

    public int check(Integer score){
        if(score == null){
            return 3;
        }
        if (score>=90&&score<=100){
            return 0;
        }
        if (score>=80&&score<=89){
            return 1;
        }
        if (score>=60&&score<=79){
            return 2;
        }
        else{
            return 3;
        }
    }

    @Override
    public void clearUserAuthorityInfo(String username) {
        redisUtil.del("Authority:" + username);
    }

    @Override
    public void clearUserAuthorityInfoByRoleId(Long roleId) {
        List<School> sysUsers = this.list(new QueryWrapper<School>()
                .inSql("id", "select user_id from user_role where role_id = " + roleId));
        sysUsers.forEach(u -> {
            this.clearUserAuthorityInfo(u.getSchoolName());
        });

    }

    @Override
    public void clearUserAuthorityInfoByMenuId(Long menuId) {
        List<School> sysUsers = schoolMapper.listByMenuId(menuId);
        sysUsers.forEach(u -> {
            this.clearUserAuthorityInfo(u.getSchoolName());
        });
    }


    @Override
    public String getUserAuthorityInfo(Long userId) {
        // 获取到Role_权限字符串，
        List<Role> roles = roleService.list(new QueryWrapper<Role>().inSql("id", "select role_id from user_role where user_id=" + userId+" and is_delete=0 "));
        String authorityInfo = null;
        // 当前的角色数大于0时处理转化为字符串
        if (redisUtil.get("Authority:"+getById(userId).getSchoolName())!=null){
            authorityInfo= (String) redisUtil.get("Authority:"+getById(userId).getSchoolName());
        }else {
            if (roles.size()>0){
                String roleCodes = roles.stream().map(t -> "ROLE_" + t.getCode()).collect(Collectors.joining(","));
                authorityInfo=roleCodes.concat(",");
            }
            // 继续获取权限菜单信息
            List<Long> menuIds= menuMapper.getMenuIds(userId);
            if (menuIds.size()!=0){
                List<Menu> menus = menuService.listByIds(menuIds);
                if (menus.size()>0){
                    String menuPrems=menus.stream().map(t->t.getPerms()).collect(Collectors.joining(","));
                    authorityInfo+=menuPrems;
                }
            }else {
                throw new BusException("没有权限");
            }
            // 将用户信息存储至redis
            redisUtil.set("Authority:"+getById(userId).getSchoolName(),authorityInfo);
        }

        return authorityInfo;
    }

    public String getNewTime(String schoolName){ // 获取学习的最新时间字符串
        List<StuExecl> collect = stuExeclService.list(new LambdaQueryWrapper<StuExecl>().eq(StuExecl::getSchoolName, schoolName))
                .stream().sorted(Comparator.comparing(StuExecl::getGmtCreate).reversed()).collect(Collectors.toList());
        if(collect == null || collect.size() == 0){
            return null;
        }

        String substring1 = collect.get(0).getGmtCreate().toString().substring(0, 10);
        String substring2 = substring1 + " " + collect.get(0).getGmtCreate().toString().substring(11);

        return substring2;
    }

    public String getRightTime(String s){
        StringBuilder s0 = new StringBuilder(s);
        s0.setCharAt(10,' ');
        return s0.toString();
    }

}
